﻿/*
 *	Copyright (c) 2009 Queensland University of Technology. All rights reserved.
 *	The QUT Bioinformatics Collection is open source software released under the 
 *	Microsoft Public License (Ms-PL): http://www.microsoft.com/opensource/licenses.mspx.
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using QUT.Bio.Util;

namespace QUT.Bio.Tags {
	public partial class ObjectTagAdder : UserControl {
		private PopupDialog dialog = new PopupDialog();
		private IEnumerable<WrappedRdfTag> currentTags;

		public ObjectTagAdder() {
			InitializeComponent();

			if ( Tags.AllTagsLoaded ) {
				RefreshSuggestionList();
			}
			else {
				Tags.WhenTagsLoaded += RefreshSuggestionList;
			}

			if ( !Tags.OntologyTemplatesLoaded ) {
				Tags.WhenOntologyTemplatesLoaded += RefreshSuggestionList;
			}

		}

		public PopupDialog Dialog {
			get {
				return dialog;
			}
		}

		public object Subject {
			get;
			set;
		}

		public IEnumerable<WrappedRdfTag> CurrentTags {
			get {
				return currentTags;
			}
			set {
				currentTags = value;
				RefreshSuggestionList();
			}
		}

		public IObjectSelector ObjectSelector {
			get;
			set;
		}

		public Action PostProcess {
			get;
			set;
		}

		private void FilterClicked( object sender, RoutedEventArgs e ) {
			RefreshSuggestionList();
		}

		private void FilterTextChanged( object sender, TextChangedEventArgs e ) {
			RefreshSuggestionList();

			string label = filterText.Text.Trim().ToLower();

			plusButton.IsEnabled = !Tags.TagTemplates.ContainsKey( label );
		}

		private void RefreshSuggestionList() {
			List<CategorisedRdfTagTemplate> templates = new List<CategorisedRdfTagTemplate>();

			templates.AddRange( from l in Tags.TagTemplates.Values
								from t in l
								where AvailableForSuggestion( t )
								select t );

			templates.Sort();

			tagSelector.AllItems = from t in templates
								   select (ISelectable) t;
		}

		private bool AvailableForSuggestion( CategorisedRdfTagTemplate template ) {
			if ( CurrentTags != null && CurrentTags.Contains( template ) ) {
				return false;
			}

			string filter = filterText.Text.Trim().ToLower();

			if ( filter != "" ) {
				if ( !template.Tag.TagLabelName.ToLower().StartsWith( filter ) ) {
					return false;
				}
			}

			bool tagMatchesUser = (bool) myTagCheckBox.IsChecked && template.IsMine
				|| (bool) myFriendsCheckBox.IsChecked && template.IsFriend
				|| (bool) anonCheckBox.IsChecked && template.IsAnonymous;

			bool tagMatchesOntology = (bool) goCheckBox.IsChecked && template.IsOntology["go"]
				|| (bool) keywordCheckBox.IsChecked && template.IsOntology["keywords"];

			return (bool) andButton.IsChecked ? tagMatchesUser && tagMatchesOntology : tagMatchesUser || tagMatchesOntology;
		}

		private void PlusButtonClicked( object sender, RoutedEventArgs e ) {
			string label = filterText.Text.Trim().ToLower();

			if ( label.Length > 0 ) {
				tagSelector.AddToSelection( Tags.CreateTemplateForUser( label ) );
				plusButton.IsEnabled = false;
			}
		}

		private void WindowChanged( PopupWindow window, WindowChangeEventType eventType ) {
			if ( eventType == WindowChangeEventType.WindowClosed ) {
				if ( dialog.Action == DialogAction.Ok ) {
					if ( (bool) justThisObjectButton.IsChecked && Subject != null ) {
						Tags.CreateTags( from t in tagSelector.SelectedItems
										 select (CategorisedRdfTagTemplate) t, new object[] { Subject }, delegate() {
							if ( PostProcess != null ) {
								PostProcess();
							}
						} );
					}
					else if ( (bool) selectedObjectButton.IsChecked && ObjectSelector != null ) {
						object[] selectedObjects = ObjectSelector.SelectedObjects;

						if ( selectedObjects != null ) {
							Tags.CreateTags( from t in tagSelector.SelectedItems
											 select (CategorisedRdfTagTemplate) t, selectedObjects, delegate() {
								if ( PostProcess != null ) {
									PostProcess();
								}
							} );
						}
					}
				}
			}
		}
	}
}
